/*
 * serial_manager.h
 * 串口管理模块头文件
 * 
 * 说明：该模块负责串口设备的连接、配置和状态管理，是串口调试工具的核心模块之一。
 */

#ifndef SERIAL_MANAGER_H
#define SERIAL_MANAGER_H

#include <QObject>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QStringList>
#include <QMap>
#include <QTimer>
#include <QDateTime>

/**
 * @brief 串口信息结构体，存储串口的详细信息
 */
struct SerialPortInfo {
    enum Status { Available, Busy, NotFound };
    QString portName;        // 端口名称
    QString displayText;     // 显示文本
    QString description;     // 端口描述
    bool isConnected;        // 是否被本应用连接
    bool isAvailable;        // 是否可连接
    bool isConnectedByApp;   // 是否被本应用连接（实现使用）
    bool isBusyByOther;      // 是否被其他应用占用
    QDateTime lastCheckTime; // 最近一次检测时间
    QDateTime lastAvailableTime; // 最近一次可用时间
    QStringList dataBitsList;// 支持的数据位列表
    bool dataBitsChecked;    // 数据位检测状态标识
    Status status;           // 端口状态
};

/**
 * @brief 串口管理类，负责串口的连接、配置和状态管理
 * 
 * 该类封装了所有串口相关的操作，包括串口扫描、连接、断开、配置等功能，
 * 并提供信号通知机制。
 */
class SerialManager : public QObject
{
    Q_OBJECT

public:
    /**
     * @brief 构造函数
     * @param parent 父对象
     */
    explicit SerialManager(QObject *parent = nullptr);
    
    /**
     * @brief 析构函数
     */
    ~SerialManager();
    
    // 新增/对齐到实现的接口
    void setupSerialPort();
    QStringList populatePortList();
    QStringList populatePortListFast();
    QStringList populateBaudRateList();
    QStringList populateDataBitsList();
    QStringList populateStopBitsList();
    QStringList populateParityList();
    QStringList populateFlowControlList();

    void startPortDetection();
    void stopPortDetection();

    /**
     * @brief 连接到指定串口
     * @param portName 串口名称
     * @param baudRate 波特率
     * @param dataBits 数据位
     * @param parity 校验位
     * @param stopBits 停止位
     * @param flowControl 流控
     * @return 是否连接成功
     */
    bool connectPort(const QString &portName, int baudRate,
                    QSerialPort::DataBits dataBits = QSerialPort::Data8,
                    QSerialPort::Parity parity = QSerialPort::NoParity,
                    QSerialPort::StopBits stopBits = QSerialPort::OneStop,
                    QSerialPort::FlowControl flowControl = QSerialPort::NoFlowControl);
    
    /**
     * @brief 断开串口连接
     */
    void disconnectPort();
    
    /**
     * @brief 发送数据
     * @param data 要发送的数据
     * @return 发送的字节数
     */
    qint64 sendData(const QByteArray &data);
    
    /**
     * @brief 获取当前连接状态
     * @return 是否已连接
     */
    bool isPortConnected() const;
    
    /**
     * @brief 获取当前连接的端口名称
     * @return 端口名称
     */
    QString getCurrentPortName() const;
    
    /**
     * @brief 更新端口状态缓存
     */
    void updatePortStatusCache();
    
    QList<QSerialPort::DataBits> detectSupportedDataBits(const QString &portName);
    QSerialPort* getSerialPort() const;
    QString getLastError() const;
    QList<SerialPortInfo> getAvailablePorts() const;
    /**
     * @brief 获取端口信息
     * @param portName 端口名称
     * @return 端口信息结构体
     */
    SerialPortInfo getPortInfo(const QString &portName) const;

signals:
    /**
     * @brief 数据接收信号
     * @param data 接收到的数据
     */
    void dataReceived(const QByteArray &data);
    
    /**
     * @brief 连接状态变化信号
     * @param connected 是否连接
     */
    void connectionStatusChanged(bool connected);
    
    /**
     * @brief 错误发生信号
     * @param errorMessage 错误信息
     */
    void errorOccurred(const QString &errorMessage);
    
    /**
     * @brief 端口列表更新信号
     * @param ports 新的端口列表
     */
    void portListUpdated(const QStringList &ports);

    /**
     * @brief 端口状态可能已变更（定时检测触发）
     */
    void portStatusChanged();

private slots:
    /**
     * @brief 读取串口数据
     */
    void readData();
    
    /**
     * @brief 处理串口错误
     * @param error 错误类型
     */
    void handleError(QSerialPort::SerialPortError error);

    /**
     * @brief 定时检测串口可用性
     */
    void checkSerialPortsAvailability();
private:
    QSerialPort *serialPort;            // 串口对象
    QTimer *portCheckTimer;             // 端口检测定时器
    QMap<QString, SerialPortInfo> portInfoCache; // 端口信息缓存
    QDateTime lastPortCheckTime;        // 最后一次检测时间
    QMap<QString, QList<QSerialPort::DataBits>> portSupportedDataBitsCache; // 数据位缓存
    QString lastError;                  // 最近错误信息

    // 私有辅助方法（与实现对齐）
    void updatePortDisplayText(SerialPortInfo &info);
    bool checkPortBusy(const QString &portName);
    bool setPortParameters(const QString &portName, int baudRate,
                           const QString &dataBits, const QString &stopBits,
                           const QString &parity, const QString &flowControl);
    bool connectPort(); // 内部无参连接（实现存在）
};

#endif // SERIAL_MANAGER_H